

/**
 * 泛型函数:在typescript用来实现函数的重用并且具有固定返回值类型和入参类型一致的能力
 */
 function getInputVal<T>(arg:T):T{
    console.log('arg: ', arg);
    return arg;
}
const identity1 = <T>(art:T):T=>{
    return art;

}
const num:number = getInputVal<number>(3333);
const val = getInputVal('auto set type')
console.log('val: ', val);
console.log('num: ', num);
/**
 * 泛型接口：当我们调用函数想要返回值有多重类型时，可以使用接口定义的泛型来实现
 */
interface Identities<V,M>{
    value:V;
    message: M;
}
  
const getMultiInputVal = <T,U>(value:T,message:U):Identities<T,U>=>{
    let identies:Identities<T,U> = {
        value,
        message
    }
    return identies
}
const multiVal:Identities<number,string> = getMultiInputVal(100,'This is a string!')
console.log('multiVal: ', multiVal);

// type initvalType = typeof getMultiInputVal;
// const demo:initvalType = (value:string,nu:number)=> {
//     return {value:value,message:nu}
// }
/**
 * 泛型类型：与泛型接口相似
 */
class IdentitiesClass<T>{
    value:T;
    constructor(val:T){
        this.value = val
    }
    getIdentity(): T {
        return this.value
      }
}
// 泛型的约束: 定义我们传入的变量都具备length属性并且length属性都是number类型
interface LengthWise{
    length: number;
}

const identifyTypeWise =<T extends LengthWise>(arg:T):T=>{
    console.log('arg: ', arg);
    return arg
}
identifyTypeWise("test length") //字符串具备length，编译通过
identifyTypeWise(["test length"]) //数组具备length，编译通过
// identifyTypeWise(3) //number类型不具备length，编译报错
/**
 * 内置的泛型处理函数-Partial
 * Partial该工具类型能够构造一个新类型，并将实际类型参数T中的所有属性变为可选属性。
 * @params 类型
 * @returns 新类型
 */
interface Student{
    name:string;
    weight: number;
    height: number;
    score: number;
    phone?: number;
}
const xmStu: Student = {
    name:"xm",
    weight: 133,
    height: 99,
    score: 122
}
type StudentPartial = Partial<Student>;

const xhStu:StudentPartial = {
    name: 'xh'
}
/**
 * 内置的泛型处理函数-Required
 * 该工具类型能够构造一个新类型，并将实际类型参数T中的所有属性变为必选属
 * @params 类型
 * @returns 新类型
 */
type StudentRequired = Required<StudentPartial>
const xjStu:StudentRequired = {
    name: 'xj'
}
/**
 * 内置的泛型处理函数-Record
 * 该工具类型能够构造一个新类型，型。“Record<K, T>”工具类型中的类型参数K提供了对象属性名联合类型，类型参数T提供了对象属性的类型
 * @params 类型
 * @returns 新类型
 */
type Obj1 = Record<string, string>
type FruitTypes = 'apple' | 'banana' | 'pear'
type FruitsWeight = Partial<Record<FruitTypes, number>>
const fruits: FruitsWeight = {
  apple: 3,
  banana: 3,
  pear: 2
}
// Pick
type AppleWeight = Pick<FruitsWeight,'apple'>
const apple:AppleWeight = {
    apple:3
}
//